import os
import sys
from datetime import datetime

from ssh_run import SshRun


class CompareWrite(SshRun):
    def __init__(self):
        super(CompareWrite, self).__init__()

    @staticmethod
    def print_info(msg: str):
        now_time = datetime.strftime(datetime.now(), '%Y-%m-%d %H:%M:%S')
        print(f'[{now_time}] {msg}')

    @staticmethod
    def print_error(msg: str):
        now_time = datetime.strftime(datetime.now(), '%Y-%m-%d %H:%M:%S')
        print(f"\033[31m[{now_time}] {msg}\033[0m")

    @staticmethod
    def get_file_size(fpath):
        fsize = os.path.getsize(fpath)
        # 换算成MB
        fsize = fsize / float(1024 * 1024)

        return fsize

    def compare(self, list1, list2, v1, v2, desc, up_user, di_user):
        text = ''
        same_list = list()
        diff_dict = {'cmd': desc, 'diff': []}
        list1_to_str = '\n'.join(list1).replace(' ', '')
        list2_to_str = '\n'.join(list2).replace(' ', '')
        if len(list1) < len(list2):
            max_num = len(list2)
        else:
            max_num = len(list1)
        for i in range(max_num):
            if i < len(list1) and i < len(list2):
                if list1[i].replace(' ', '').replace(up_user, '').replace(
                        di_user, '') not in list2_to_str:
                    diff_dict['diff'].append(
                        {'upgrade': list1[i], 'direct': ''})
                    text += f'upgrade{v1}:\033[32m{list1[i]}\033[0m' \
                        f' ---VS--- ' \
                        f'direct{v2}:\033[32m""\033[0m\n'
                else:
                    same_list.append(list1[i])
                if list2[i].replace(' ', '').replace(up_user, '').replace(
                        di_user, '') not in list1_to_str:
                    diff_dict['diff'].append(
                        {'upgrade': '', 'direct': list2[i]})
                    text += f'upgrade{v1}:\033[32m""\033[0m' \
                        f' ---VS--- ' \
                        f'direct{v2}:\033[32m{list2[i]}\033[0m\n'
                else:
                    if list2[i] not in same_list:
                        same_list.append(list2[i])
            else:
                if i < len(list1):
                    if list1[i].replace(' ', '').replace(up_user, '').replace(
                            di_user, '') not in list2_to_str:
                        diff_dict['diff'].append(
                            {'upgrade': list1[i], 'direct': ''})
                        text += f'upgrade{v1}:\033[32m{list1[i]}\033[0m' \
                            f' ---VS--- ' \
                            f'direct{v2}:\033[32m""\033[0m\n'
                elif i < len(list2):
                    if list2[i].replace(' ', '').replace(up_user, '').replace(
                            di_user, '') not in list1_to_str:
                        diff_dict['diff'].append(
                            {'upgrade': '', 'direct': list2[i]})
                        text += f'upgrade{v1}:\033[32m""\033[0m' \
                            f' ---VS--- ' \
                            f'direct{v2}:\033[32m{list2[i]}\033[0m\n'
        text += '\n\n\n'
        if len(text.strip()) > 0:
            self.print_error(desc)
            self.print_info(text)
        return same_list, diff_dict

    def write_file(self, file_path, file_num, file_text):
        if os.path.exists(file_path):
            file_size = self.get_file_size(file_path)
            if file_size >= 10:
                new_name = str(os.path.basename(file_path).split('.')[0]) + \
                           f'_{file_num}' + os.path.splitext(file_path)[-1]
                file_path = os.path.join(os.path.dirname(file_path), new_name)
                file_num += 1
        if n == 1:
            mode = 'w'
        else:
            mode = 'a'
        with open(file_path, mode, encoding='utf-8', errors='ignore') as f:
            f.write(file_text)
        return file_num


if __name__ == '__main__':
    upgrade = {'ip': sys.argv[1],
               'username': sys.argv[2],
               'pwd': sys.argv[3],
               'db_name': sys.argv[4],
               'db_port': sys.argv[5],
               'db_version': sys.argv[6],
               'db_env': sys.argv[7]}
    direct = {'ip': sys.argv[8],
              'username': sys.argv[9],
              'pwd': sys.argv[10],
              'db_name': sys.argv[11],
              'db_port': sys.argv[12],
              'db_version': sys.argv[13],
              'db_env': sys.argv[14]}
    cw = CompareWrite()

    data_dict = {'system_table': [],
                 'system_view': [],
                 'meta_cmd': []}

    cw.print_info('系统表校验，先检验表名，再校验表结构，最后校验表内容')
    command = 'select distinct (schemaname,tablename) as a ' \
              'from pg_tables order by a;'
    pg_tables_1 = cw.conn_and_run(command, True, **upgrade).replace(
        upgrade['username'], '').splitlines()
    pg_tables_2 = cw.conn_and_run(command, True, **direct).replace(
        direct['username'], '').splitlines()
    same, diff = cw.compare(pg_tables_1, pg_tables_2, upgrade['db_version'],
                            direct['db_version'], command,
                            upgrade['username'], direct['username'])
    data_dict['system_table'].append(diff)
    for st in same:
        if ',' in st:
            tmp = st[2:-1].split(',')
            command = f'\\d+ {tmp[0]}.{tmp[1]}'
            pg_tables_1 = cw.conn_and_run(command, True, **upgrade).replace(
                upgrade['username'], '').splitlines()
            pg_tables_2 = cw.conn_and_run(command, True, **direct).replace(
                direct['username'], '').splitlines()
            s1, d1 = cw.compare(pg_tables_1, pg_tables_2,
                                upgrade['db_version'],
                                direct['db_version'], command,
                                upgrade['username'], direct['username'])
            data_dict['system_table'].append(d1)

    cw.print_info('系统视图校验，先检验视图名，再校验视图结构，最后校验视图内容')
    command = 'select distinct (schemaname,viewname) as a ' \
              'from pg_views order by a;'
    pg_tables_1 = cw.conn_and_run(command, True, **upgrade).replace(
        upgrade['username'], '').splitlines()
    pg_tables_2 = cw.conn_and_run(command, True, **direct).replace(
        direct['username'], '').splitlines()
    same, diff = cw.compare(pg_tables_1, pg_tables_2, upgrade['db_version'],
                            direct['db_version'], command,
                            upgrade['username'], direct['username'])
    data_dict['system_view'].append(diff)
    for st in same:
        if ',' in st:
            tmp = st[2:-1].split(',')
            command = f'\\d+ {tmp[0]}.{tmp[1]}'
            pg_tables_1 = cw.conn_and_run(command, True, **upgrade).replace(
                upgrade['username'], '').splitlines()
            pg_tables_2 = cw.conn_and_run(command, True, **direct).replace(
                direct['username'], '').splitlines()
            s1, d1 = cw.compare(pg_tables_1, pg_tables_2,
                                upgrade['db_version'],
                                direct['db_version'], command,
                                upgrade['username'], direct['username'])
            data_dict['system_view'].append(d1)

    n = 1
    f_path = os.path.join(os.getcwd(), 'log', upgrade["db_version"],
                          'system_table.diff')
    os.makedirs(os.path.dirname(f_path), exist_ok=True)
    context = f'{upgrade["db_version"]} vs 直接安装{direct["db_version"]}\n\n'
    for row in data_dict.get('system_table', None):
        cmd = row.get('cmd', None)
        diff = row.get('diff', None)
        if len(diff) > 0:
            context += cmd + '\n'
            for j in diff:
                context += str(j) + '\n'
            context += '\n\n'
    cw.write_file(f_path, n, context)
    cw.print_info('系统表对比完成')

    n = 1
    f_path = os.path.join(os.getcwd(), 'log', upgrade["db_version"],
                          'system_view.diff')
    context = f'{upgrade["db_version"]} vs 直接安装{direct["db_version"]}\n\n'
    for row in data_dict.get('system_view', None):
        cmd = row.get('cmd', None)
        diff = row.get('diff', None)
        if len(diff) > 0:
            context += cmd + '\n'
            for j in diff:
                context += str(j) + '\n'
            context += '\n\n'
    cw.write_file(f_path, n, context)

    cw.print_info('系统视图对比完成')
